/*
 * Copyright (c) 2020-2021. the original authors and DEPSEA.ORG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.depsea.oss.config;

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import org.depsea.oss.client.PresignedUrlGenerator;
import org.depsea.oss.client.minio.MinioCustomerBucketOssTemplate;
import org.depsea.oss.client.minio.MinioOssTemplate;
import org.depsea.oss.client.minio.MinioPresignedUrlGenerator;
import org.depsea.oss.config.properties.MinioProperties;
import org.depsea.oss.exception.OssException;
import org.depsea.oss.filter.FileUploadFilter;
import org.depsea.oss.strategy.FilenameHandleStrategy;
import org.depsea.oss.strategy.RandomFilenameHandleStrategyImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * 自动装配
 *
 * @author Wang Chengwei
 * @since 1.0.0 2021/11/30 15:37
 */
@Configuration
@EnableConfigurationProperties({
        MinioProperties.class
})
@ConditionalOnClass(MinioClient.class)
public class MinioOssConfiguration {

    @Bean
    @ConditionalOnMissingBean(MinioClient.class)
    @ConditionalOnProperty(value = "spring.oss.minio.enable", havingValue = "true")
    public MinioClient minioClient(MinioProperties minioProperties) {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(minioProperties.getEndpoint())
                .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
                .build();
        // 创建默认Bucket
        try {
            BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder()
                    .bucket(minioProperties.getDefaultBucketName())
                    .build();
            if (!minioClient.bucketExists(bucketExistsArgs)) {
                minioClient.makeBucket(
                        MakeBucketArgs.builder()
                                .bucket(minioProperties.getDefaultBucketName())
                                .build()
                );
            }
        } catch (Exception e) {
            throw new OssException("无法创建默认Bucket");
        }
        return minioClient;
    }

    @Bean
    @ConditionalOnMissingBean(MinioOssTemplate.class)
    @ConditionalOnBean(MinioClient.class)
    public MinioOssTemplate minioOssTemplate(
            MinioClient minioClient, MinioProperties minioProperties,
            @Autowired(required = false) FilenameHandleStrategy filenameHandleStrategy,
            @Autowired(required = false) List<FileUploadFilter> filterList) {
        MinioOssTemplate minioOssTemplate = new MinioOssTemplate(minioClient, minioProperties.getDefaultBucketName());
        if (filenameHandleStrategy != null) {
            minioOssTemplate.setFilenameHandleStrategy(filenameHandleStrategy);
        }
        minioOssTemplate.addFilters(filterList);
        return minioOssTemplate;
    }

    @Bean
    @ConditionalOnMissingBean(MinioCustomerBucketOssTemplate.class)
    @ConditionalOnBean(MinioClient.class)
    public MinioCustomerBucketOssTemplate minioCustomerBucketOssTemplate(
            MinioClient minioClient, MinioProperties minioProperties,
            @Autowired(required = false) FilenameHandleStrategy filenameHandleStrategy,
            @Autowired(required = false) List<FileUploadFilter> filterList) {
        MinioCustomerBucketOssTemplate minioOssTemplate = new MinioCustomerBucketOssTemplate(minioClient);
        if (filenameHandleStrategy != null) {
            minioOssTemplate.setFilenameHandleStrategy(new RandomFilenameHandleStrategyImpl());
        }
        minioOssTemplate.setAutoCreateBucket(minioProperties.isAutoCreateBucket());
        minioOssTemplate.addFilters(filterList);
        return minioOssTemplate;
    }

    @Bean
    @ConditionalOnMissingBean(MinioPresignedUrlGenerator.class)
    @ConditionalOnBean(MinioClient.class)
    public MinioPresignedUrlGenerator minioPresignedUrlGenerator(MinioClient minioClient, MinioProperties minioProperties) {
        return new MinioPresignedUrlGenerator(minioClient, minioProperties.getDefaultBucketName());
    }

}
